package cn.itcast.service.cargo.impl;

import cn.itcast.dao.cargo.*;
import cn.itcast.domain.cargo.*;
import cn.itcast.service.cargo.InvoiceService;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import java.util.*;

@Service(timeout = 10000)
public class InvoiceServiceImpl implements InvoiceService {

    @Autowired
    private InvoiceDao invoiceDao;
    @Autowired
    private ShippingDao shippingDao;
    @Autowired
    private PackingDao packingDao;
    @Autowired
    private ExportDao exportDao;
    @Autowired
    private ContractDao contractDao;
    @Autowired
    private ExportProductDao exportProductDao;

    private Double US_DOLLAR_CURRENCY = 6.53;

    @Override
    public PageInfo<Invoice> findAllByPage(InvoiceExample example, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        List<Invoice> invoices = invoiceDao.selectByExample(example);
        return new PageInfo<>(invoices);
    }

    /**
     * 保存的时候进行修改
     * 修改packing 中的发票信息
     * 修改shipping 中的状态
     * @param invoice
     */
    @Override
    public void save(Invoice invoice) {
        Shipping shipping = shippingDao.selectByPrimaryKey(invoice.getInvoiceId());
        Packing packing = packingDao.selectByPrimaryKey(shipping.getShippingOrderId());
        packing.setInvoiceNo(invoice.getInvoiceNo());
        packing.setInvoiceDate(invoice.getInvoiceDate());
        packing.setState(2);
        //修改shipping中状态
        shipping.setState(1);
        //修改发票状态
        invoice.setState(0);
        //保存
        packingDao.updateByPrimaryKeySelective(packing);
        shippingDao.updateByPrimaryKeySelective(shipping);
        invoiceDao.insertSelective(invoice);
    }

    @Override
    public void delete(String id) {
        //修改装箱
        Packing packing = packingDao.selectByPrimaryKey(id);
        packing.setInvoiceNo("");
        packing.setInvoiceDate(null);
        packing.setState(1);
        //修改委托单状态
        Shipping shipping = shippingDao.selectByPrimaryKey(id);
        shipping.setState(0);
        packingDao.updateByPrimaryKeySelective(packing);
        shippingDao.updateByPrimaryKeySelective(shipping);
        //删除自己
        invoiceDao.deleteByPrimaryKey(id);
    }

    @Override
    public void updateByKey(Invoice invoice) {

    }

    @Override
    public Invoice selectByPrimaryKey(String id) {
        return invoiceDao.selectByPrimaryKey(id);
    }

    /**
     * 报销合同号  去packing中找
     * 贸易条款   去购销合同找
     * 发票金额    注意发票关注的是总费用，美金。（按美金结算）
     * @param id
     * @return
     */
    @Override
    public Invoice toAdd(String id) {
        Shipping shipping = shippingDao.selectByPrimaryKey(id);
        Invoice invoice = new Invoice();
        //拿到报运合同号
        Packing packing = packingDao.selectByPrimaryKey(id);
        invoice.setScNo(packing.getExportNos());
        //贸易条款 用，进行隔开 从购销合同中去中找
        //先得到exportids
        String exportIds = packing.getExportIds();
        if (!StringUtils.isEmpty(exportIds)) {
            List<String> exportIdList = Arrays.asList(exportIds.split(","));
            ExportExample exportExample = new ExportExample();
            exportExample.createCriteria().andIdIn(exportIdList);
            List<String> contractIdsList = new ArrayList<>();
            //报运金额
            Double reportedAmount = 0.0;
            getReportedAmountAndContractIds(reportedAmount,contractIdsList,exportExample);
            //收集所有的购销合同id
            List<String> contractAllIds = collectAllContract(contractIdsList);
            //贸易条款
            StringBuilder tradeTerms = new StringBuilder("");
            //查找所有的contract
            ContractExample contractExample = new ContractExample();
            contractExample.createCriteria().andIdIn(contractAllIds);
            List<Contract> contracts = contractDao.selectByExample(contractExample);
            contracts.forEach(item -> {
                if (!StringUtils.isEmpty(item.getTradeTerms())) {
                    tradeTerms.append(item.getTradeTerms()).append(",");
                }
            });
            //去除最后一个逗号
            String tradeTermsString = tradeTerms.deleteCharAt(tradeTerms.length() - 1).toString();
            //发票金额  (报运金额 + 装箱金额 + 委托金额（录入）) 这里要用美金的汇率进行计算
            Double endAmount = ((reportedAmount + packing.getPackingMoney() + shipping.getFreight()) *US_DOLLAR_CURRENCY);
            //封装
            invoice.setTradeTerms(tradeTermsString);
            invoice.setInvoiceId(id);
            invoice.setInvoiceMoney(endAmount);
        }
        return invoice;
    }

    @Override
    public Map<String, Boolean> safeToDelete(String id) {
        Integer state = invoiceDao.selectByPrimaryKey(id).getState();
        Map<String,Boolean> map = new HashMap<>();
        map.put("flag", state == 0);
        return map;
    }

    private void getReportedAmountAndContractIds(Double amount,List<String> contractIds,ExportExample exportExample) {
        List<Export> exports = exportDao.selectByExample(exportExample);
        List<String> exportIds = new ArrayList<>();
        exports.forEach(item -> {
            if (!StringUtils.isEmpty(item.getContractIds())) {
                contractIds.add(item.getContractIds());
            }
            exportIds.add(item.getId());
        });
        ExportProductExample exportProductExample = new ExportProductExample();
        exportProductExample.createCriteria().andExportIdIn(exportIds);
        List<ExportProduct> exportProducts = exportProductDao.selectByExample(exportProductExample);
        for(ExportProduct ep : exportProducts) {
            if (ep.getCnumber() != null) {
                amount += ep.getCnumber();
            }
        }
    }


    //一个String 是一个 购销合同,购销合同 这种
    private List<String> collectAllContract(List<String> ids) {
        List<String> contractList = new ArrayList<>();
        for (String contractIdString : ids){
            if (!StringUtils.isEmpty(contractIdString)) {
                List<String> cidS = Arrays.asList(contractIdString.split(","));
                contractList.addAll(cidS);
            }
        }
        return contractList;
    }
}
